package com.gary.util;
import com.gary.annotations.CheckDataPermission;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import java.io.File;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * <p> Madison.lu </p>
 * <p>Version: 1.0.0</p>
 * <p>Create Date： 2019/11/1 14:52 </p>
 * <p>Copyright (c) 2017 ~ 2019 Allchips版权所有</p>
 */
public class CheckDataPermissionUtil {


    private static final Logger log = LoggerFactory.getLogger(CheckDataPermissionUtil.class);

    public static List<String> getAllCheckDataPermissionTable(String locationPattern) {

        List<Class> clazzs = loadClassesByPackage(locationPattern);
        Set<String> tableNameSet = new HashSet<>();
        clazzs.forEach((clazz) -> {
            if (!clazz.isInterface()) {
                // 如果类未被@CheckDataPermission注解，结束本轮循环
                Method[] methods = clazz.getDeclaredMethods();
                if (CommUtils.isNull(methods)) {
                    return;
                }
                for (Method method : methods) {
                    CheckDataPermission checkDataPermission = method.getAnnotation(CheckDataPermission.class);
                    if (CommUtils.isNull(checkDataPermission)) {
                        continue;
                    }
                    //解析方法上注解信息
                    String[] tableNameArr = handleAnnotationData(checkDataPermission);
                    if (CommUtils.isNull(tableNameArr)) {
                        continue;
                    }
                    for (int i = 0; i < tableNameArr.length; i++) {
                        tableNameSet.add(tableNameArr[i]);
                    }
                }
            }
        });
        ArrayList<String> tableNameList = new ArrayList<>(tableNameSet);
        return tableNameList;
    }

    /**
     * @Description: 初始化加載注解信息
     * @Author: Richard Zhan
     * @Date: 2019/10/29
     **/
    private void parseInterfaceMappingPath() {
        List<Class> classes = loadClassesByPackage("");

    }

    /**
     * 累加从注解上获取到的路径
     *
     * @param annotation
     * @return
     */
    private static String[] handleAnnotationData(CheckDataPermission annotation) {
        if (CommUtils.isNotNull(annotation)) {
            String[] pathArr = annotation.tableName();
            if (CommUtils.isNotNull(pathArr) && pathArr.length > 0) {
                return pathArr;
            }
        }
        return null;
    }


    /**
     * @Description: 获取指定路径下的所有接口实现类
     * @Author: Richard Zhan
     * @Date: 2019/10/29
     **/
    private static List<Class> loadClassesByPackage(String locationPattern) {
        List<File> directories = new ArrayList<>();
        try {
            PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
            Resource[] classPathResources = resolver.getResources(locationPattern);
            if (CommUtils.isNull(classPathResources) || classPathResources.length <= 0) return null;
            for (int i = 0; i < classPathResources.length; i++) {
                Resource resource = classPathResources[i];
                File file = null;
                if (resource.exists()) {
                    file = new File(resource.getURL().getFile());
                }
                if (CommUtils.isNotNull(file)) {
                    directories.add(file);
                }
            }
        } catch (Exception e) {
            log.error("loadClassesByPackage异常", e);
        }
        ArrayList<Class> classes = new ArrayList<>();
        for (File file : directories) {
            if (file.getName().endsWith(".class")) {
                try {
                    String path = file.getPath();
                    String className = path.substring(path.lastIndexOf(File.separator) + 1);
                    className = className.substring(0, className.length() - 6);
                    String classPackage = path.substring(path.indexOf("com"), path.lastIndexOf(File.separator));
                    classPackage = classPackage.replace(File.separator, ".");
                    String fullClassPath = classPackage + "." + className;
                    classes.add(Class.forName(fullClassPath));
                } catch (NoClassDefFoundError e) {
                    log.error("加载接口,解析路径找不到对应的类", e);
                    e.printStackTrace();
                } catch (ClassNotFoundException e) {
                    log.error("加载接口,解析路径找不到对应的类", e);
                    e.printStackTrace();
                }
            }
        }
        return classes;
    }
}
